package com.taomeng.util;

import com.github.pagehelper.Page;
import com.taomeng.entity.PageBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowMapper;

import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * jdbcTemplate 封装类
 **/
@Slf4j
public class JdbcTemplateSupport extends JdbcTemplate {
    public JdbcTemplateSupport() {
    }

    public JdbcTemplateSupport(DataSource dataSource) {
        super(dataSource);
    }

    public JdbcTemplateSupport(DataSource dataSource, boolean lazyInit) {
        super(dataSource, lazyInit);
    }

    public <T> PageBean<T> queryForPage(String sql, Page<T> pagination, RowMapper<T> rowMapper) throws DataAccessException {

        return queryForPage(sql, pagination, new PreparedStatementSetter() {
            @Override
            public void setValues(java.sql.PreparedStatement preparedStatement) throws SQLException {
                return;
            }
        }, rowMapper);
    }

    /**
     * @param sql        sql语句
     * @param pagination 分页信息
     * @param key        模糊查询关键词
     * @param num        需要模糊查询的字段数量        有几个 ? 问号 ，就传数字几
     * @param rowMapper  返回的封装类class
     * @param <T>        泛型（封装类）
     * @return pageBean
     * @throws DataAccessException
     */
    public <T> PageBean<T> queryForPage(String sql, Page<T> pagination, String key, Integer num, RowMapper<T> rowMapper) throws DataAccessException {

        return queryForPage(sql, pagination, new PreparedStatementSetter() {
            @Override
            public void setValues(java.sql.PreparedStatement preparedStatement) throws SQLException {
                for (int i = 1; i <= num; i++) {
                    preparedStatement.setString(i, "%" + key + "%");
                }
            }
        }, rowMapper);
    }
    /**
     * @param sql        sql语句
     * @param pagination 分页信息
     * @param key        模糊查询关键词
     * @param num        需要模糊查询的字段数量        有几个 ? 问号 ，就传数字几
     * @param rowMapper  返回的封装类class
     * @param <T>        泛型（封装类）
     * @return pageBean
     * @throws DataAccessException
     */
    public <T> PageBean<T> queryForPage(String sql, Page<T> pagination, Integer key, Integer num, RowMapper<T> rowMapper) throws DataAccessException {

        return queryForPage(sql, pagination, new PreparedStatementSetter() {
            @Override
            public void setValues(java.sql.PreparedStatement preparedStatement) throws SQLException {
                for (int i = 1; i <= num; i++) {
                    preparedStatement.setInt(i,key);
                }
            }
        }, rowMapper);
    }

    public <T> PageBean<T> queryForPage(String sql, Page<T> pagination, PreparedStatementSetter var2, RowMapper<T> var3) throws DataAccessException {

        PageBean<T> result = new PageBean<T>();

        //获取记录条数
        String countSql = "select count(1) as count from (" + sql + ") temp";
        log.info("countSql {}", countSql);
        List<Integer> countList = super.query(countSql, var2, new RowMapper<Integer>() {
            public Integer mapRow(ResultSet resultSet, int i) throws SQLException {
                return new Integer(resultSet.getInt("count"));
            }
        });


        result.setTotal(countList.get(0));
        result.setSize(countList.get(0));
        result.setPageNum(pagination.getPageNum());
        result.setPageSize(pagination.getPageSize());

        int pageCount = result.getSize() % result.getPageSize();
        result.setPages(pageCount == 0 ? (result.getSize() / result.getPageSize()) : (result.getSize() / result.getPageSize() + 1));

        sql += parseLimit(result);
        log.info("queryLimitSql {}", sql);

        List<T> data = super.query(sql, var2, var3);
        result.setList(data);
        return result;
    }

    private <T> String parseLimit(PageBean<T> pagination) {

        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(" ");
        stringBuffer.append("limit");
        stringBuffer.append(" ");
        if (pagination.getPageNum() == 0) {
            stringBuffer.append("0");
        } else {
            stringBuffer.append((pagination.getPageNum() - 1) * pagination.getPageSize());
        }
        stringBuffer.append(",");
        stringBuffer.append(pagination.getPageSize());

        return stringBuffer.toString();
    }
}
